package com.org.es7.conponents.elasticsearch;

import com.org.platform.utils.CommonUtil;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig.Builder;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder.HttpClientConfigCallback;
import org.elasticsearch.client.RestClientBuilder.RequestConfigCallback;
import org.elasticsearch.client.RestHighLevelClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

/**
 * @author duheng
 * @Date 2021/6/13 16:59
 */
@Component
public class EsInit implements InitializingBean, Ordered {

	private final static Logger log = LoggerFactory.getLogger(EsInit.class);

	private static final String esClient = "esClient";

	private static final Map<String, RestHighLevelClient> restHighLevelClientMap = new ConcurrentHashMap<>();

	@Autowired
	private ElasticSearchConfig elasticSearchConfig;

	@Override
	public void afterPropertiesSet() throws Exception {
		fillEsConfig(elasticSearchConfig);
	}

	public static RestHighLevelClient getRestHighLevelClient() {
		return restHighLevelClientMap.get(esClient);
	}

	private void fillEsConfig(ElasticSearchConfig esConfig) {
		if (null == esConfig) {
			log.error("init elasticsearch-config error....");
			return;
		}
		String hostName = esConfig.getHostname();
		if (CommonUtil.isNullOrEmpty(hostName)) {
			log.error("init elasticsearch-host error....");
			return;
		}
		String port = esConfig.getPort();
		if (CommonUtil.isNullOrEmpty(port)) {
			log.error("init elasticsearch-port error....");
			return;
		}
		String schemeName = esConfig.getSchemeName();
		if (CommonUtil.isNullOrEmpty(schemeName)) {
			log.error("init elasticsearch-scheme error....");
			return;
		}
		String[] hostArray = hostName.split(",");
		String[] portArray = port.split(",");
		String[] schemeArray = schemeName.split(",");
		if (hostArray.length != portArray.length || hostArray.length != schemeArray.length) {
			log.error(" init elasticsearch-httphost error....");
			return;
		}
		HttpHost[] httpHosts = new HttpHost[hostArray.length];
		for (int i = 0; i < hostArray.length; i++) {
			httpHosts[i] = new HttpHost(hostArray[i], Integer.valueOf(portArray[i]), schemeArray[i]);
		}
		RestHighLevelClient restHighLevelClient = new RestHighLevelClient(
				RestClient.builder(httpHosts)
						.setRequestConfigCallback(new RequestConfigCallback() {
							@Override
							public Builder customizeRequestConfig(Builder requestConfigBuilder) {
								requestConfigBuilder.setSocketTimeout(esConfig.getSocketTimeOut());
								requestConfigBuilder.setConnectTimeout(esConfig.getConnectionTimeOut());
								requestConfigBuilder.setConnectionRequestTimeout(esConfig.getConnectionRequestTimeOut());
								return requestConfigBuilder;
							}
						}).setHttpClientConfigCallback(new HttpClientConfigCallback() {
					@Override
					public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpAsyncClientBuilder) {
						httpAsyncClientBuilder.setMaxConnTotal(esConfig.getMaxConnectTotal());
						httpAsyncClientBuilder.setMaxConnPerRoute(esConfig.getMaxConnectPerRoute());
						httpAsyncClientBuilder.setKeepAliveStrategy(EsConnectionKeepAliveStrategy.INSTANCE);
						if (!CommonUtil.isNullOrEmpty(esConfig.getUserName()) && !CommonUtil.isNullOrEmpty(esConfig.getUserPass())) {
							final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
							credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(esConfig.getUserName(), esConfig.getUserPass()));
							httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
						}
						return httpAsyncClientBuilder;
					}
				}));
		restHighLevelClientMap.put(esClient, restHighLevelClient);
	}

	@Override
	public int getOrder() {
		return 1;
	}
}
